package cn.sc.summer.mybatis.handler;

import cn.hutool.core.text.CharSequenceUtil;
import cn.hutool.core.util.StrUtil;
import cn.sc.summer.constant.mybatisplus.context.TenantContextHolder;
import cn.sc.summer.mybatis.model.BaseTenantModel;
import cn.sc.summer.mybatis.util.MPUserUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.handlers.MetaObjectHandler;
import com.baomidou.mybatisplus.core.toolkit.IdWorker;
import cn.sc.summer.constant.enums.StatusEnum;
import cn.sc.summer.constant.mybatisplus.TenantInfo;
import cn.sc.summer.constant.util.AssertUtil;
import cn.sc.summer.token.po.UserDetailX;
import lombok.extern.slf4j.Slf4j;
import org.apache.ibatis.reflection.MetaObject;
import org.springframework.stereotype.Component;

import java.util.Date;

/**
 * 类名：对标记有默认填充的列做数据填充
 *
 * @author a-xin
 * @date 2023/12/20 16:38
 * @see BaseTenantModel
 */
@Slf4j
@Component
public class MyMetaObjectHandler implements MetaObjectHandler {

    /**
     * 插入时的填充策略
     *
     * @param metaObject 元对象
     */
    @Override
    public void insertFill(MetaObject metaObject) {
        JSONObject objectInfo = JSONObject.parseObject(JSONObject.toJSONString(metaObject.getOriginalObject()));
        String updateUser = objectInfo.getOrDefault("updateUser", "").toString();
        String createUser = objectInfo.getOrDefault("createUser", "").toString();
        String dataTenantId = objectInfo.getOrDefault("dataTenantId", "").toString();
        String id = objectInfo.getOrDefault("id", "").toString();

        this.setFieldValByName("id", StrUtil.isNotBlank(id) ? id : IdWorker.getIdStr(), metaObject);
        if (MPUserUtil.hasLoginStatus()) {
            UserDetailX loginUser = MPUserUtil.getLoginUser();

            TenantInfo tenantInfo = TenantContextHolder.getTenantInfo();
            if (!tenantInfo.getIgnoreTenant() && CharSequenceUtil.isBlank(dataTenantId)) {
                this.setFieldValByName("dataTenantId", StrUtil.isNotBlank(dataTenantId) ? dataTenantId : tenantInfo.getTenantId(), metaObject);
            }

            this.setFieldValByName("updateUser", StrUtil.isNotBlank(updateUser) ? updateUser : loginUser.getUserId(), metaObject);
            this.setFieldValByName("createUser", StrUtil.isNotBlank(createUser) ? createUser : loginUser.getUserId(), metaObject);
        } else {
            AssertUtil.functionIfPre(dataTenantId, CharSequenceUtil::isNotBlank,
                    () -> this.setFieldValByName("dataTenantId", StrUtil.isNotBlank(dataTenantId) ? dataTenantId : "1", metaObject));

            this.setFieldValByName("updateUser", StrUtil.isNotBlank(updateUser) ? updateUser : "1", metaObject);
            this.setFieldValByName("createUser", StrUtil.isNotBlank(createUser) ? createUser : "1", metaObject);
        }
        this.setFieldValByName("createTime", new Date(), metaObject);
        this.setFieldValByName("updateTime", new Date(), metaObject);
        this.setFieldValByName("del", StatusEnum.ENABLE_OR_NOT_DELETED.getType(), metaObject);
    }

    /**
     * 更新时的填充策略
     *
     * @param metaObject 元对象
     */
    @Override
    public void updateFill(MetaObject metaObject) {
        JSONObject objectInfo = JSONObject.parseObject(JSONObject.toJSONString(metaObject.getOriginalObject()));
        String updateUser = objectInfo.getOrDefault("updateUser", "").toString();
        if (MPUserUtil.hasLoginStatus()) {
            this.setFieldValByName("updateUser", StrUtil.isNotBlank(updateUser) ? updateUser : MPUserUtil.getLoginUser().getTenantId(), metaObject);
        } else {
            this.setFieldValByName("updateUser", StrUtil.isNotBlank(updateUser) ? updateUser : "1", metaObject);
        }
        this.setFieldValByName("updateTime", new Date(), metaObject);
    }

}


